<template>
  <g :transform="`translate(${x}, ${y})`">
    <!-- 定义渐变和遮罩 -->
    <defs>
      <!-- 立体效果渐变 -->
      <linearGradient id="cell-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
        <stop offset="0%" style="stop-color:#ffffff;stop-opacity:1" />
        <stop offset="100%" style="stop-color:#e6e6e6;stop-opacity:1" />
      </linearGradient>
      <!-- 货架边框渐变 -->
      <linearGradient id="shelf-border-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
        <stop offset="0%" style="stop-color:#a0a0a0;stop-opacity:1" />
        <stop offset="50%" style="stop-color:#808080;stop-opacity:1" />
        <stop offset="100%" style="stop-color:#606060;stop-opacity:1" />
      </linearGradient>
      <!-- 货架立柱渐变 -->
      <radialGradient id="pillar-gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
        <stop offset="0%" style="stop-color:#808080;stop-opacity:1" />
        <stop offset="70%" style="stop-color:#606060;stop-opacity:1" />
        <stop offset="100%" style="stop-color:#404040;stop-opacity:1" />
      </radialGradient>
      <!-- 货架层板渐变 -->
      <linearGradient id="shelf-layer-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" style="stop-color:#d9d9d9;stop-opacity:1" />
        <stop offset="50%" style="stop-color:#bfbfbf;stop-opacity:1" />
        <stop offset="100%" style="stop-color:#d9d9d9;stop-opacity:1" />
      </linearGradient>
      <!-- 金属质感渐变 -->
      <linearGradient id="metal-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
        <stop offset="0%" style="stop-color:#f0f0f0;stop-opacity:1" />
        <stop offset="50%" style="stop-color:#e0e0e0;stop-opacity:1" />
        <stop offset="100%" style="stop-color:#d0d0d0;stop-opacity:1" />
      </linearGradient>
      <!-- 阴影滤镜 -->
      <filter id="shelf-shadow" x="-20%" y="-20%" width="140%" height="140%">
        <feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
        <feOffset dx="2" dy="2" result="offsetblur"/>
        <feComponentTransfer>
          <feFuncA type="linear" slope="0.2"/>
        </feComponentTransfer>
        <feMerge>
          <feMergeNode/>
          <feMergeNode in="SourceGraphic"/>
        </feMerge>
      </filter>
    </defs>

    <!-- 货架底板阴影 -->
    <rect
      x="4"
      y="4"
      :width="totalWidth - 4"
      :height="totalHeight - 4"
      fill="#000000"
      opacity="0.1"
      filter="url(#shelf-shadow)"
    />

    <!-- 货架底板 -->
    <rect
      x="0"
      y="0"
      :width="totalWidth"
      :height="totalHeight"
      fill="url(#shelf-layer-gradient)"
      stroke="#c0c0c0"
      stroke-width="1"
    />

    <!-- 货架网格 -->
    <g class="shelf-grid">
      <line
        v-for="row in rows + 1"
        :key="'h-' + row"
        :x1="0"
        :y1="(row - 1) * (cellHeight + cellSpacing)"
        :x2="totalWidth"
        :y2="(row - 1) * (cellHeight + cellSpacing)"
        stroke="#d0d0d0"
        stroke-width="1"
      />
      <line
        v-for="col in cols + 1"
        :key="'v-' + col"
        :x1="(col - 1) * (cellWidth + cellSpacing)"
        :y1="0"
        :x2="(col - 1) * (cellWidth + cellSpacing)"
        :y2="totalHeight"
        stroke="#d0d0d0"
        stroke-width="1"
      />
    </g>

    <!-- 库位组 -->
    <g v-for="row in computedLayout" :key="row.id">
      <g v-for="cell in row.cells" :key="cell.id">
        <!-- 货架立柱和支撑结构 -->
        <g class="shelf-structure">
          <!-- 立柱阴影 -->
          <circle
            v-for="(pos, index) in [
              { x: cell.x, y: cell.y },
              { x: cell.x + cellWidth, y: cell.y },
              { x: cell.x, y: cell.y + cellHeight },
              { x: cell.x + cellWidth, y: cell.y + cellHeight }
            ]"
            :key="'pillar-shadow-' + index"
            :cx="pos.x + 2"
            :cy="pos.y + 2"
            r="5"
            fill="#000000"
            opacity="0.1"
          />
          <!-- 立柱 -->
          <g v-for="(pos, index) in [
            { x: cell.x, y: cell.y },
            { x: cell.x + cellWidth, y: cell.y },
            { x: cell.x, y: cell.y + cellHeight },
            { x: cell.x + cellWidth, y: cell.y + cellHeight }
          ]" :key="'pillar-' + index">
            <circle
              :cx="pos.x"
              :cy="pos.y"
              r="5"
              fill="url(#pillar-gradient)"
              stroke="#404040"
              stroke-width="1"
            />
            <circle
              :cx="pos.x"
              :cy="pos.y"
              r="2"
              fill="#808080"
            />
          </g>
          <!-- 支撑横梁 -->
          <rect
            :x="cell.x"
            :y="cell.y"
            :width="cellWidth"
            height="3"
            fill="url(#metal-gradient)"
            stroke="#a0a0a0"
            stroke-width="0.5"
          />
          <rect
            :x="cell.x"
            :y="cell.y + cellHeight - 3"
            :width="cellWidth"
            height="3"
            fill="url(#metal-gradient)"
            stroke="#a0a0a0"
            stroke-width="0.5"
          />
          <!-- 支撑竖梁 -->
          <rect
            :x="cell.x"
            :y="cell.y"
            width="3"
            :height="cellHeight"
            fill="url(#metal-gradient)"
            stroke="#a0a0a0"
            stroke-width="0.5"
          />
          <rect
            :x="cell.x + cellWidth - 3"
            :y="cell.y"
            width="3"
            :height="cellHeight"
            fill="url(#metal-gradient)"
            stroke="#a0a0a0"
            stroke-width="0.5"
          />
        </g>

        <!-- 库位主体 -->
        <g :transform="`translate(${cell.x}, ${cell.y})`" class="storage-slot">
          <!-- 库位底板 -->
          <rect
            x="4"
            y="4"
            :width="cellWidth - 8"
            :height="cellHeight - 8"
            :class="[
              'storage-cell',
              { 'cell-occupied': cell.status === 'occupied' },
              `cell-type-${cell.type}`
            ]"
            fill="url(#cell-gradient)"
            stroke="#e0e0e0"
            stroke-width="1"
            rx="2"
            ry="2"
            @mouseenter="handleCellHover({...cell, area: areaName})"
            @mouseleave="$emit('cell-leave')"
            @click="handleCellClick(cell)"
          />
          <!-- 库位内部纹理 -->
          <g v-if="cell.status === 'empty'" class="cell-pattern">
            <line
              v-for="i in 3"
              :key="'h-line-' + i"
              :x1="8"
              :y1="(cellHeight - 8) * i / 4 + 4"
              :x2="cellWidth - 8"
              :y2="(cellHeight - 8) * i / 4 + 4"
              stroke="#f0f0f0"
              stroke-width="1"
            />
            <line
              v-for="i in 3"
              :key="'v-line-' + i"
              :x1="(cellWidth - 8) * i / 4 + 4"
              :y1="8"
              :x2="(cellWidth - 8) * i / 4 + 4"
              :y2="cellHeight - 8"
              stroke="#f0f0f0"
              stroke-width="1"
            />
          </g>
          <!-- 库位编号 -->
          <text
            :x="cellWidth / 2"
            :y="cellHeight / 2"
            class="cell-text"
            text-anchor="middle"
            alignment-baseline="middle"
          >
            {{ cell.number }}
          </text>
        </g>
      </g>
    </g>

    <!-- 正面视图弹窗 -->


    <!-- 通道 -->
    <!-- <template v-if="showAisle">
      <g class="aisle-container"> -->
        <!-- 通道背景 -->
        <!-- <rect
          v-if="aisleDirection === 'vertical'"
          :x="aislePosition - 25"
          y="-10"
          width="50"
          :height="totalHeight + 20"
          fill="#f5f5f5"
          opacity="0.9"
        />
        <rect
          v-else
          x="-10"
          :y="aislePosition - 25"
          :width="totalWidth + 20"
          height="50"
          fill="#f5f5f5"
          opacity="0.9"
        /> -->
        <!-- 通道纹理 -->
        <!-- <g v-if="aisleDirection === 'vertical'" class="aisle-pattern">
          <line
            v-for="i in Math.ceil(totalHeight / 15)"
            :key="'aisle-h-' + i"
            :x1="aislePosition - 15"
            :y1="i * 15 - 10"
            :x2="aislePosition + 15"
            :y2="i * 15 - 10"
            class="aisle-line"
          />
          <line
            :x1="aislePosition"
            y1="0"
            :x2="aislePosition"
            :y2="totalHeight"
            class="aisle-center-line"
          />
        </g>
        <g v-else class="aisle-pattern">
          <line
            v-for="i in Math.ceil(totalWidth / 15)"
            :key="'aisle-v-' + i"
            :x1="i * 15 - 10"
            :y1="aislePosition - 15"
            :x2="i * 15 - 10"
            :y2="aislePosition + 15"
            class="aisle-line"
          />
          <line
            x1="0"
            :y1="aislePosition"
            :x2="totalWidth"
            :y2="aislePosition"
            class="aisle-center-line"
          />
        </g>
      </g>
    </template> -->

    <!-- 区域标题 -->
    <text
      v-if="areaNamePosition === 'top'"
      :x="totalWidth / 2"
      :y="totalHeight - 120"
      class="area-title"
      @click="handleAreaClick"
    >
      {{ areaName }}
    </text>
    <text
      v-if="areaNamePosition === 'left'"
      :x="-80"
      :y="40"
      class="area-title"
      @click="handleAreaClick"
    >
      {{ areaName }}
    </text>
    <text
        v-if="areaNamePosition === 'right'"
        :x="totalWidth + 20"
        :y="40"
        class="area-title"
        @click="handleAreaClick"
    >
      {{ areaName }}
    </text>
    <text
        v-if="areaNamePosition === 'bottom'"
      :x="totalWidth / 2"
      :y="totalHeight + 40"
      class="area-title"
      text-anchor="middle"
      @click="handleAreaClick"
    >
      {{ areaName }}
    </text>
  </g>
</template>

<script setup lang="ts" name="StorageArea">
import type { StorageCell, StorageRow } from '../../../types/warehouse'
import { shallowRef, watch } from 'vue'

interface Props {
  x: number // 区域X坐标
  y: number // 区域Y坐标
  rows: number // 行数
  cols: number // 列数
  cellWidth: number // 单元格宽度
  cellHeight: number // 单元格高度
  cellSpacing: number // 单元格间距
  direction: 'horizontal' | 'vertical' // 库位排列方向
  startNumber: number // 起始编号
  showAisle: boolean // 是否显示通道
  aisleDirection: 'horizontal' | 'vertical' // 通道方向
  aislePosition: number // 通道位置
  areaName: string // 区域名称
  areaNamePosition: 'top' | 'bottom' // 区域名称位置
  cellTypes: string[] // 库位类型
  numberingPattern?: number[][] // 自定义编号模式
  gaps?: Array<{ position: number; width: number }> // 间隔配置，包含位置和对应的宽度
}

const props = withDefaults(defineProps<Props>(), {
  x: 0,
  y: 0,
  rows: 5,
  cols: 5,
  cellWidth: 60,
  cellHeight: 60,
  cellSpacing: 10,
  direction: 'horizontal',
  startNumber: 1,
  showAisle: true,
  aisleDirection: 'vertical',
  aislePosition: 200,
  areaName: '',
  areaNamePosition: 'top',
  cellTypes: () => ['default'],
  numberingPattern: undefined,
  gaps: () => []
})

const emit = defineEmits<{
  (e: 'cell-hover', cell: StorageCell & { area: string }): void
  (e: 'cell-leave'): void
  (e: 'cell-click', cell: StorageCell & { area: string }): void
  (e: 'area-click', name: string, cells: StorageCell[]): void
}>()

const selectedCell = ref<StorageCell | null>(null)

const handleCellHover = (cell: StorageCell) => {
  emit('cell-hover', { ...cell, area: props.areaName })
}

const handleCellClick = (cell: StorageCell) => {
  selectedCell.value = cell
  emit('cell-click', { ...cell, area: props.areaName })
}

const handleAreaClick = () => {
  // 获取当前区域的所有库位
  const allCells = computedLayout.value.flatMap(row => row.cells)
  emit('area-click', props.areaName, allCells)
}

// 计算总宽度和高度
const totalWidth = computed(() => {
  const baseWidth = props.cols * (props.cellWidth + props.cellSpacing)
  const gapsWidth = props.gaps.reduce((sum, gap) => sum + gap.width, 0)
  return baseWidth + gapsWidth
})
const totalHeight = computed(() => props.rows * (props.cellHeight + props.cellSpacing))

// 缓存 computedLayout，只有相关 props 变化时才重新计算
const computedLayoutCache = shallowRef<StorageRow[] | null>(null)
let lastPropsSnapshot = ''

const getPropsSnapshot = () => {
  // 只序列化影响布局的 props 字段
  return JSON.stringify({
    rows: props.rows,
    cols: props.cols,
    cellWidth: props.cellWidth,
    cellHeight: props.cellHeight,
    cellSpacing: props.cellSpacing,
    direction: props.direction,
    startNumber: props.startNumber,
    numberingPattern: props.numberingPattern,
    gaps: props.gaps
  })
}

const computeLayout = () => {
  const layout: StorageRow[] = []
  let cellNumber = props.startNumber
  for (let row = 0; row < props.rows; row++) {
    const cells: StorageCell[] = []
    let extraOffset = 0
    for (let col = 0; col < props.cols; col++) {
      const cellTypeIndex = Math.floor(Math.random() * props.cellTypes.length)
      const number = props.numberingPattern
        ? props.numberingPattern[row][col]
        : cellNumber++
      const gap = props.gaps.find(g => g.position === col)
      if (gap) {
        extraOffset += gap.width
      }
      cells.push({
        id: `cell-${row}-${col}`,
        number,
        status: Math.random() > 0.5 ? 'occupied' : 'empty',
        type: props.cellTypes[cellTypeIndex],
        x: col * (props.cellWidth + props.cellSpacing) + extraOffset,
        y: row * (props.cellHeight + props.cellSpacing)
      })
    }
    layout.push({
      id: `row-${row}`,
      cells
    })
  }
  return layout
}

// 监听 props 变化，只有 props 变化时才重新计算布局
watch(
  () => getPropsSnapshot(),
  (newSnapshot) => {
    if (newSnapshot !== lastPropsSnapshot) {
      computedLayoutCache.value = computeLayout()
      lastPropsSnapshot = newSnapshot
    }
  },
  { immediate: true }
)

const computedLayout = computed(() => computedLayoutCache.value || [])

defineOptions({
  name: 'StorageArea'
})

defineExpose({
  totalWidth,
  totalHeight,
  computedLayout
})
</script>

<style scoped>
.storage-cell {
  fill: #ffffff;
  stroke: none;
  cursor: pointer;
  transition: all 0.3s;
  filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.1));
}

.storage-cell:hover {
  fill: #e6f7ff;
  filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.2));
  transform: translate(-1px, -1px);
}

.cell-occupied {
  fill: #fafafa;
  filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.15));
}

.cell-type-default {
  fill: url(#cell-gradient);
}

.cell-type-raw {
  fill: #f6ffed;
}

.cell-type-finished {
  fill: #e6f7ff;
}

.cell-type-wip {
  fill: #fff7e6;
}

.cell-text {
  font-size: 14px;
  fill: #595959;
  user-select: none;
  font-weight: 500;
  filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.1));
}

.shelf-grid line {
  stroke: #e8e8e8;
  stroke-width: 1;
  stroke-dasharray: 2, 2;
}

.shelf-structure {
  pointer-events: none;
}

.storage-slot {
  transform-origin: center center;
  transition: transform 0.3s ease;
}

/* .storage-slot:hover {
  transform: scale(1.02);
} */

.cell-pattern line {
  stroke: #f0f0f0;
  stroke-width: 1;
  stroke-dasharray: 4, 4;
}

.aisle-container {
  pointer-events: none;
}

.aisle-pattern {
  opacity: 0.6;
}

.aisle-line {
  stroke: #d9d9d9;
  stroke-width: 1;
  stroke-dasharray: 4, 2;
}

.aisle-center-line {
  stroke: #bfbfbf;
  stroke-width: 2;
  stroke-dasharray: 8, 4;
}

.area-title {
  font-size: 16px;
  font-weight: bold;
  fill: #262626;
  filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.1));
  cursor: pointer;
  transition: fill 0.3s;
}

.area-title:hover {
  fill: #1890ff;
}

.popup-title {
  font-size: 16px;
  font-weight: bold;
  fill: #262626;
}

.close-button {
  cursor: pointer;
}

.close-button:hover circle {
  fill: #e6e6e6;
}
</style>
